package com.movies.service.controller.admin;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckRole;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.movies.service.common.Constants;
import com.movies.service.common.Result;
import com.movies.service.entity.Cinema;
import com.movies.service.entity.Seat;
import com.movies.service.service.CinemaService;
import com.movies.service.service.SeatService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
// 新增：JSON 解析
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.ArrayList;


@RestController
@RequestMapping("/admin/seat")
@SaCheckLogin
@SaCheckRole("ADMIN")
public class AdminSeatController {

    @Autowired
    private SeatService seatService;
    @Autowired
    private CinemaService cinemaService;

//    分页查询座位列表（支持按影院ID/影厅/座位号/类型筛选）
    @GetMapping("/page")
    public Result page(@RequestParam(defaultValue = "1") Integer pageNo,
                       @RequestParam(defaultValue = "10") Integer pageSize,
                       @RequestParam(required = false) Long cinemaId,
                       @RequestParam(required = false) String hallName,
                       @RequestParam(required = false) String seatNo,
                       @RequestParam(required = false) String seatType) {
        LambdaQueryWrapper<Seat> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(cinemaId != null, Seat::getCinemaId, cinemaId)
                .like(hallName != null && !hallName.isEmpty(), Seat::getHallName, hallName)
                .like(seatNo != null && !seatNo.isEmpty(), Seat::getSeatNo, seatNo)
                .eq(seatType != null && !seatType.isEmpty(), Seat::getSeatType, seatType);
        Page<Seat> page = seatService.page(new Page<>(pageNo, pageSize), wrapper);
        return Result.success("查询成功", page);
    }

//    新增座位；自动填充影院名称；成功后同步 t_cinema.hall_list，确保新增的影厅被包含
    @PostMapping("/create")
    public Result create(@RequestBody Seat seat) {
        if (seat.getCinemaId() == null) {
            return Result.error(Constants.CODE_600, "必须指定影院ID");
        }
        if (seat.getHallName() == null || seat.getHallName().isEmpty()) {
            return Result.error(Constants.CODE_600, "必须指定影厅名称");
        }
        if (seat.getSeatNo() == null || seat.getSeatNo().isEmpty()) {
            return Result.error(Constants.CODE_600, "必须指定座位号");
        }
        if (seat.getCinemaName() == null || seat.getCinemaName().isEmpty()) {
            Cinema c = cinemaService.getById(seat.getCinemaId());
            if (c != null) {
                seat.setCinemaName(c.getCname());
            }
        }
        // 唯一约束：同影院 + 同影厅 不得重复座位号
        LambdaQueryWrapper<Seat> uniqW = new LambdaQueryWrapper<>();
        uniqW.eq(Seat::getCinemaId, seat.getCinemaId())
             .eq(Seat::getHallName, seat.getHallName())
             .eq(Seat::getSeatNo, seat.getSeatNo());
        if (seatService.count(uniqW) > 0) {
            return Result.error(Constants.CODE_600, "该影院该影厅已存在此座位号，不能重复");
        }
        boolean ok = seatService.save(seat);
        if (!ok) {
            return Result.error(Constants.CODE_600, "新增失败");
        }
        // 同步影院 hall_list
        syncAddHallToCinema(seat.getCinemaId(), seat.getHallName());
        return Result.success("新增成功");
    }

//    更新座位；若影厅名称变化，向新影厅加入 hall_list；如果旧影厅已无座位则从 hall_list 移除
    @PutMapping("/update")
    public Result update(@RequestBody Seat seat) {
        if (seat.getId() == null) {
            return Result.error(Constants.CODE_600, "缺少ID");
        }
        // 记录旧值以判断是否更换影厅或影院
        Seat old = seatService.getById(seat.getId());
        Long oldCinemaId = old != null ? old.getCinemaId() : null;
        String oldHall = old != null ? old.getHallName() : null;
        String oldSeatNo = old != null ? old.getSeatNo() : null;
        Long newCinemaId = seat.getCinemaId() != null ? seat.getCinemaId() : oldCinemaId;
        String newHall = seat.getHallName() != null ? seat.getHallName() : oldHall;
        String newSeatNo = seat.getSeatNo() != null ? seat.getSeatNo() : oldSeatNo;
        // 唯一约束：同影院 + 同影厅 不得重复座位号（排除自身）
        if (newCinemaId != null && newHall != null && newSeatNo != null) {
            LambdaQueryWrapper<Seat> uniqW = new LambdaQueryWrapper<>();
            uniqW.eq(Seat::getCinemaId, newCinemaId)
                 .eq(Seat::getHallName, newHall)
                 .eq(Seat::getSeatNo, newSeatNo)
                 .ne(Seat::getId, seat.getId());
            if (seatService.count(uniqW) > 0) {
                return Result.error(Constants.CODE_600, "该影院该影厅已存在此座位号，不能重复");
            }
        }
        boolean ok = seatService.updateById(seat);
        if (!ok) {
            return Result.error(Constants.CODE_600, "更新失败");
        }
        // 新影厅加入 hall_list
        syncAddHallToCinema(newCinemaId, newHall);
        // 旧影厅如果已无该影院座位，移除
        if (!equalsSafe(oldCinemaId, newCinemaId) || !equalsSafe(oldHall, newHall)) {
            maybeRemoveHallFromCinema(oldCinemaId, oldHall);
        }
        return Result.success("更新成功");
    }

//    删除座位；若该影院下该影厅已无座位，自动从 hall_list 移除
    @DeleteMapping("/{id}")
    public Result delete(@PathVariable Long id) {
        // 查询座位以获得影院与影厅
        Seat seat = seatService.getById(id);
        boolean ok = seatService.removeById(id);
        if (!ok) {
            return Result.error(Constants.CODE_600, "删除失败");
        }
        if (seat != null) {
            maybeRemoveHallFromCinema(seat.getCinemaId(), seat.getHallName());
        }
        return Result.success("删除成功");
    }

//    批量删除座位；按影院-影厅维度检查并清理 hall_list
    @DeleteMapping("/batch")
    public Result deleteBatch(@RequestBody List<Long> ids) {
        // 预取需要检查的影院-影厅组合
        List<Seat> toDelete = (ids == null || ids.isEmpty()) ? new java.util.ArrayList<>() : seatService.list(new LambdaQueryWrapper<Seat>().in(Seat::getId, ids));
        boolean ok = seatService.removeByIds(ids);
        if (!ok) {
            return Result.error(Constants.CODE_600, "批量删除失败");
        }
        // 删除后逐个检查是否需要从 hall_list 移除
        for (Seat s : toDelete) {
            maybeRemoveHallFromCinema(s.getCinemaId(), s.getHallName());
        }
        return Result.success("批量删除成功");
    }


    // 空安全的 equals 比较
    private boolean equalsSafe(Object a, Object b) {
        return a == b || (a != null && a.equals(b));
    }


    // 将影院 hallList(JSON 字符串) 解析为 List<String>，兼容 null/"null"/非法
    private List<String> parseHallList(String hallRaw) {
        List<String> halls = new ArrayList<>();
        try {
            if (hallRaw != null && !hallRaw.trim().isEmpty() && !"null".equalsIgnoreCase(hallRaw.trim())) {
                ObjectMapper mapper = new ObjectMapper();
                halls = mapper.readValue(hallRaw, new TypeReference<List<String>>(){});
            }
        } catch (Exception ignored) {}
        return halls;
    }


    // 将指定影厅加入影院的 hall_list（若不存在），失败时忽略异常以保证主流程。
    private void syncAddHallToCinema(Long cinemaId, String hallName) {
        if (cinemaId == null || hallName == null || hallName.isEmpty()) return;
        Cinema c = cinemaService.getById(cinemaId);
        if (c == null) return;
        List<String> halls = parseHallList(c.getHallList());
        if (!halls.contains(hallName)) {
            halls.add(hallName);
            try {
                ObjectMapper mapper = new ObjectMapper();
                c.setHallList(mapper.writeValueAsString(halls));
                cinemaService.updateById(c);
            } catch (Exception ignored) {}
        }
    }

    // 如果影院下某影厅已无座位，则从 hall_list 中移除该影厅。
    private void maybeRemoveHallFromCinema(Long cinemaId, String hallName) {
        if (cinemaId == null || hallName == null || hallName.isEmpty()) return;
        LambdaQueryWrapper<Seat> w = new LambdaQueryWrapper<>();
        w.eq(Seat::getCinemaId, cinemaId).eq(Seat::getHallName, hallName);
        long count = seatService.count(w);
        if (count == 0) {
            Cinema c = cinemaService.getById(cinemaId);
            if (c == null) return;
            List<String> halls = parseHallList(c.getHallList());
            if (halls.remove(hallName)) {
                try {
                    ObjectMapper mapper = new ObjectMapper();
                    c.setHallList(mapper.writeValueAsString(halls));
                    cinemaService.updateById(c);
                } catch (Exception ignored) {}
            }
        }
    }

//    获取座位详情
    @GetMapping("/{id}")
    public Result get(@PathVariable Long id) {
        if (id == null) {
            return Result.error(Constants.CODE_600, "缺少ID");
        }
        Seat seat = seatService.getById(id);
        return seat != null ? Result.success("查询成功", seat) : Result.error(Constants.CODE_600, "未找到座位");
    }
}